package generator.workflow.sfj;

import generator.datastructure.ForkPoint;
import generator.datastructure.MethodDeclaration;
import generator.datastructure.VarDeclaration;
import generator.workflow.PeerClassBuilder;
import generator.workflow.PeerClassDirector;

import java.util.List;

/**Esta clase permite obtener la clase peer que resulta de aplicar la paralelización
 * empleando una biblioteca objetivo que utilice el patrón de sincronización de resultados
 * SJF (single fork/join)
 * El curso de acción que define esta clase para la gneración de la clase peer se puede describir
 * mediante el siguiente pseudocódigo:<p>
 * <PRE>
 * 		AllForks = getForks(m);
 * 		loop(f = AllForks.next()){
 * 			isolateGridVariableDeclaration(f);
 * 			gridEnableFork(f);
 * 			setJoinPoints();  
 * 		} 	
 * </PRE>
 * @see {@link SFJPeerClassBuilder} para información sobre la semántica de cada función descripta
 * en el pseudocódigo.*/
public class SFJPeerClassDirector extends PeerClassDirector {
	
	
	/**Constructor vacío de la clase*/
	public SFJPeerClassDirector(){
		
	}
	
	/**@param pcb
	 * 			instancia de un PeerClassBuilder que se utilizará para generar la clase peer*/
	public SFJPeerClassDirector(PeerClassBuilder pcb){
		this.pcb = pcb;	
	}
	
	public void setPeerClassBuilder(PeerClassBuilder pcb){
		this.pcb = pcb;
	}
	
	public PeerClassBuilder getPeerClassBuilder(){
		return pcb;
	}
	
	/**Ordena la ejecución de los métodos de su colaborador {@link SFJPeerClassBuilder} que permiten definir
	 * el algoritmo de análisis y transformación de clase secuencial en clase peer para bibliotecas que utlicen
	 * el patrón de sincronización de resultados SFJ*/
	public void parallelizeMethod(MethodDeclaration md) {		
			//por cada llamado recursivo del método 
		List<ForkPoint> forks = ((SFJPeerClassBuilder)pcb).getForks(md);
		for (ForkPoint fork : forks) {
			VarDeclaration gridVariableDec = ((SFJPeerClassBuilder)pcb).isolateGridVariableDeclaration(fork);
			ForkPoint gridifiedFork = ((SFJPeerClassBuilder)pcb).gridEnableFork(fork); 				
			((SFJPeerClassBuilder)pcb).setJoinPoints(gridVariableDec,gridifiedFork);				
		}		
	}

}
